package com.hy.mydesktop.client.component.factory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.EventType;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.event.WidgetListener;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.widget.BoxComponent;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.Container;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Layout;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.hy.mydesktop.client.component.factory.ButtonFactory;

import com.hy.mydesktop.client.component.type.ComponentControllerEnum;
import com.hy.mydesktop.client.component.type.ComponentTypeEnum;
import com.hy.mydesktop.shared.persistence.domain.gxt.GxtComponentMetaModel;
import com.hy.mydesktop.shared.persistence.domain.gxt.GxtComponentMetaNodeModel;
import com.hy.mydesktop.shared.persistence.domain.gxt.constant.GxtMetaModelTypeEnum;
import com.hy.mydesktop.shared.rpc.util.ComponentControllerEnumConverter;
import com.hy.mydesktop.shared.rpc.util.ComponentTypeEnumConverter;
import com.hy.mydesktop.shared.util.log.MyLoggerUtil;


/**
 * 
 * <ul>
 * <li>开发作者：花宏宇</li>
 * <li>设计日期：2010-8-27；时间：上午11:52:08</li>
 * <li>类型名称：GxtComponentFactory</li>
 * <li>设计目的：</li>
 * </ul>
 * <ul>
 * <b>修订编号：</b>
 * <li>修订日期：</li>
 * <li>修订作者：</li>
 * <li>修订原因：</li>
 * <li>修订内容：</li>
 * </ul>
 */
public  class GxtComponentFactory {
	
	public static final  String className ="com.hy.mydesktop.client.component.factory.GxtComponentFactory";
	
	/**
	 * 
	 * <ul>
	 * <li>方法含义：GxtComponentMetaModel信息，创建控件。<br>
	 * 注；GxtComponentMetaModel必须是树形结构(只有一个根节点)
	 * </li>
	 * <li>方法作者：花宏宇</li>
	 * <li>编写日期：2010-8-28；时间：下午上午10:56:34</li>
	 * </ul>
	 * <ul>
	 * <b>修订编号：</b>
	 * <li>修订日期：</li>
	 * <li>修订作者：</li>
	 * <li>修订原因：</li>
	 * <li>修订内容：</li>
	 * </ul>
	 * @param <COMPONENT>
	 * @param gxtComponentMetaModel
	 * @return
	 */
	public static <COMPONENT extends Component> COMPONENT createGxtComponent(
			GxtComponentMetaModel gxtComponentMetaModel) {
		
		
		GxtMetaModelTypeEnum gxtMetaModelTypeEnum = gxtComponentMetaModel.getGxtMetaModelTypeEnum();
		switch (gxtMetaModelTypeEnum) {
			case BASE_GXT_META_MODEL_TYPE:
				
				return createBaseGxtComponent(gxtComponentMetaModel.getRoot());
				
			case TREE_GXT_META_MODEL_TYPE:
				
				return createTreeGxtComponent(gxtComponentMetaModel);
			default:
				return null;
		}
	}
	
	public static <COMPONENT extends Component> COMPONENT createOneGxtComponent(
			GxtComponentMetaNodeModel gxtComponentMetaNodeModel) {
		return createBaseGxtComponent(gxtComponentMetaNodeModel);
		
		
		
	}
	
	/**
	 * 根据GxtComponentMetaModel(继承BaseModel)，创建单一控件
	 * @param <COMPONENT>
	 * @param gxtComponentMetaNodeModel
	 * @return
	 */
	private static <COMPONENT extends Component> COMPONENT createBaseGxtComponent(
			GxtComponentMetaNodeModel gxtComponentMetaNodeModel) {
		//BaseModel gxtComponentMetaModel=null;
		
		COMPONENT component = null;
				
		
		
		if (gxtComponentMetaNodeModel==null) {
			MyLoggerUtil.printError(className, "某个控制器Controller对应的gxtComponentMetaNodeModel为空!");
		}
		ComponentTypeEnum componentTypeEnum = gxtComponentMetaNodeModel.getComponentTypeEnum();
		
		if (componentTypeEnum==null) {
			ComponentTypeEnumConverter.updateComponentTypeEnum(gxtComponentMetaNodeModel);
			componentTypeEnum = gxtComponentMetaNodeModel.getComponentTypeEnum();
			
			if (componentTypeEnum==null) {
				MyLoggerUtil.printError(className, "没有查询到componentTypeEnum类型");
			}else {
				MyLoggerUtil.printDebug(className, " gxtComponentMetaNodeModel.getComponentTypeEnumIndex() is "
					+gxtComponentMetaNodeModel.getComponentTypeEnumIndex()+"("+componentTypeEnum.name()+"; gxtComponentMetaNodeModel.getComponentTypeEnum() is null ;)");
			}
		}
		
		
		switch (componentTypeEnum) {
		//逐一枚举出ComponentTypeEnum中所有的控件类型
			
			case TREEPANELMODULES_MODEL: {
				component = (COMPONENT) TreePanelModulesFactory.createTreePanelModule(gxtComponentMetaNodeModel);
				break;
			}
			
			case GRIDSETMODULES_MODEL: {
				component = (COMPONENT) GridSetModulesFactory.createGridModule(gxtComponentMetaNodeModel);
				break;
			}
			case FORM_MODULE_MODEL: {
				component = (COMPONENT) FormModuleFactory.createFormModule(gxtComponentMetaNodeModel);
				break;
			}
			case BUTTON_MODEL: {
				component = (COMPONENT) ButtonFactory.createButton(gxtComponentMetaNodeModel);
				break;
			}
			
			case GRID_MODEL: {
				//component = (COMPONENT) GridFactory.createReorderingGrid(gxtComponentMetaNodeModel);
				MyLoggerUtil.printError(className, "GRID_MODEL不能有GridFactory创建");
				break;
			}
			/**
			 * 此工厂已废弃
			 */
			case EDITABLEGRID_MODEL: {
				component = (COMPONENT) EditableGridFactory.createEditorGrid(gxtComponentMetaNodeModel);
				break;
			}
			
			case WINDOW_MODEL: {
				component = (COMPONENT) WindowFactory.createWindow(gxtComponentMetaNodeModel);
				break;
			}
			//文本域
			case TEXTFIELD_MODEL: {
				component = (COMPONENT) TextFieldFactory.createTextField(gxtComponentMetaNodeModel);
				break;
			}
			//内容面板
			case CONTENTPANEL_MODEL: {
				component = (COMPONENT) ContentPanelFactory.createContentPanel(gxtComponentMetaNodeModel);
				break;
			}
			//TabItem面板
			case TABITEM_MODEL: {
				component = (COMPONENT) TabItemFactory.createTabItem(gxtComponentMetaNodeModel);
				break;
			}
			//Tab面板
			case TABPANEL_MODEL: {
				component = (COMPONENT) TabPanelFactory.createTabPanel(gxtComponentMetaNodeModel);
				break;
			}
			//菜单栏
			case MENUBAR_MODEL: {
				component = (COMPONENT)MenuBarFactory.createMenuBar(gxtComponentMetaNodeModel);
				break;
			}
			//工具栏
			case TOOLBAR_MODEL: {
				component = (COMPONENT)ToolBarFactory.createToolBar(gxtComponentMetaNodeModel);
				break;
			}
			case FIELDSET_MODEL: {
				component = (COMPONENT)FieldSetFactory.createFieldSet(gxtComponentMetaNodeModel);
				break;
			}
			//日期选择域
			case DATEFIELD_MODEL: {
				component = (COMPONENT)DateFieldFactory.createDateField(gxtComponentMetaNodeModel);
				break;
			}
			case DATEPICKER_MODEL: {
				component = (COMPONENT)DatePickerFactory.createDatePicker(gxtComponentMetaNodeModel);
				break;
			}
			//下拉选框
			case COMBOBOX_MODEL: {
				component = (COMPONENT)ComboBoxFactory.createComboBox(gxtComponentMetaNodeModel);
				break;
			}
			//简单下拉选框
			case SIMPLECOMBOBOX_MODEL: {
				component = (COMPONENT)SimpleComboBoxFactory.createSimpleComboBox(gxtComponentMetaNodeModel);
				break;
			}
			//单选框
			case RADIOGROUP_MODEL: {
				component = (COMPONENT)RadioGroupFactory.createRadioGroup(gxtComponentMetaNodeModel);
				break;
			}
			//单选框中的选项
			case RADIO_MODEL: {
				component = (COMPONENT)RadioFactory.createRadio(gxtComponentMetaNodeModel);
				break;
			}
			//复选框
			case CHECKBOXGROUP_MODEL: {
				component = (COMPONENT)CheckBoxGroupFactory.createCheckBoxGroup(gxtComponentMetaNodeModel);
				break;
			}
			//单选框中的选项
			case CHECKBOX_MODEL: {
				component = (COMPONENT)CheckBoxFactory.createCheckBox(gxtComponentMetaNodeModel);
				break;
			}
			
			//菜单栏的菜单项
			case MENUBARITEM_MODEL: {
				component = (COMPONENT)MenuItemBarFactory.createMenuBarItem(gxtComponentMetaNodeModel);
				break;
			}
			//表格面板
			case FORMPANEL_MODEL: {
				component = (COMPONENT)FormpanelFactory.createFormPanel(gxtComponentMetaNodeModel);
				break;
			}
			case TEXTAREA_MODEL: {
				component = (COMPONENT)TextAreaFactory.createTextArea(gxtComponentMetaNodeModel);
				break;
			}
			
			//图表
			case CHART_MODEL: {
				//component = (COMPONENT)ChartFactory.createChart(gxtComponentMetaNodeModel);
				break;
			}
			default: {//当componentTypeEnum为空，或者与现有控件类型不符合时
				component = null;
				break;
			}
			
			}
		MyLoggerUtil.printComponentDebugForInit(component.getClass());
			return component;
	}
	
	/**
	 * 
	 * <ul>
	 * <li>方法含义：创建具有树形结构的控件（GxtComponentMetaModel为树形结构）</li>
	 * <li>方法作者：花宏宇</li>
	 * <li>编写日期：2010-8-28；时间：下午上午10:53:22</li>
	 * </ul>
	 * <ul>
	 * <b>修订编号：</b>
	 * <li>修订日期：</li>
	 * <li>修订作者：</li>
	 * <li>修订原因：</li>
	 * <li>修订内容：</li>
	 * </ul>
	 * @param <COMPONENT>
	 * @param gxtComponentMetaModelList
	 * @return
	 */
	
	private static <COMPONENT extends Component> COMPONENT createTreeGxtComponent(
			GxtComponentMetaModel gxtComponentMetaModel) {
		//控件创建过程中，分两次遍历
		//第一次：创建对象
	
		//Map<GxtComponentMetaModel, COMPONENT> map = new HashMap<GxtComponentMetaModel, COMPONENT>();
		if(gxtComponentMetaModel.getGxtMetaModelTypeEnum()!=GxtMetaModelTypeEnum.TREE_GXT_META_MODEL_TYPE){
			return null;
		}
		
		//获取根节点
		GxtComponentMetaNodeModel root= gxtComponentMetaModel.getRoot();
		//存放遍历后，创建的控件
		Map<GxtComponentMetaNodeModel, COMPONENT> map = new HashMap<GxtComponentMetaNodeModel, COMPONENT>();
				
		GxtComponentMetaNodeModel tempNode = null;
		tempNode = root;
		
		COMPONENT tempComponent = null;
		//先序遍历树形结构
		while(tempNode!=null){
			  		//为当前节点创建对象（及赋值），并把它和对应的node，放入map
					tempComponent = createBaseGxtComponent(tempNode);
					//tempComponent.addListener(EventType, listener)
					
					// TODO 如何添加事件，以及如何处理事件
					//TODO 监听器与观察者
					//PagingLoadConfig
					/**
					 * EventType ??
					 * Listener  ??
					 * Listener<XxxEvent> ??
					 * 
					 * 如何组合
					 */
				
					
					/**
					 * 判断控件是否需要事件处理，
					 * 如果是---EventType是什么，BaseEvent是什么，handleEvent内部是如何执行的
					 */
					
					/*button.addListener(Events.Select,new Listener<BaseEvent>() {

						@Override
						public void handleEvent(BaseEvent be) {
							if (be!=null) {
								//be可以处理
								ButtonEvent buttonEvent = (ButtonEvent)be;
								buttonEvent.
							}
						}
					});
					button.addSelectionListener(new SelectionListener<ButtonEvent>() {
						
						@Override
						public void componentSelected(ButtonEvent ce) {
							*//**
							 * 获取事件处理的一个map容器---可能是window ，
							 * 如果某一控件有事件需要监听，把这个控件放入map，
							 * 把响应这个事件的控件处理，放入map中对应位置
							 *//*
						}
					});*/
					
					
			  		map.put(tempNode, tempComponent);
			  		//如当前节点存在父节点（即父节点为容器），则把当前节点加入到父节点之中
			  		if (gxtComponentMetaModel.getParent(tempNode)!=null) {
			  			
						//((LayoutContainer)map.get(gxtComponentMetaModel.getParent(tempNode))).add(tempComponent);
						GxtComponentMetaNodeModel parent	= gxtComponentMetaModel.getParent(tempNode);
						LayoutContainer layoutContainer = (LayoutContainer)map.get(parent);
						layoutContainer.add(tempComponent);
					}
			  		//获得当前节点的下一个节点
			  		tempNode = gxtComponentMetaModel.getNextNode(tempNode);		  	
			  		
		}
		
		//返回添加好各个控件的最终容器
		return map.get(root);
	}

	public static Component ItemGxtComponent(
			GxtComponentMetaNodeModel subGxtComponentMetaNodeModel) {
		
		return createBaseGxtComponent(subGxtComponentMetaNodeModel);
	}
	
	
}
